/*******************************************************************************
 * 文件名: PdfExportForTemplate.java
 * 描    述: 根据模板导出PDF
 * 创建人: Dean Huang(hudi-112@163.com)
 * 日　期: 2018-01-11
 * 描　述: 文件描述
 * 版　本: 1.0
 *******************************************************************************/

package com.z1.core.data.export.pdf;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Map;

import com.itextpdf.text.Document;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.z1.core.data.export.pdf.model.PdfTable;
import com.z1.core.data.export.pdf.model.PdfTableCell;
import com.z1.core.data.export.pdf.model.PdfTableRow;

public class PdfExportForTemplate {

	//图片前缀
	private final String IMAGE_PREFIX = "img_";
	
	private final String TABLE_DETAIL = "table_detail";
	
	private Font tableFont = null;
	
	//PDF文档流
	private ByteArrayOutputStream stream = null;
	
	public PdfExportForTemplate(String template, Map<String, Object> params, Map<String, byte[]> imageParams) throws Exception {
		this(template, params, imageParams, null);
	}
	public PdfExportForTemplate(String template, Map<String, Object> params, Map<String, byte[]> imageParams, PdfTable pdfTable) throws Exception {
		PdfReader reader = null;
		PdfStamper stamper = null;
		try {
			reader = new PdfReader(PdfExportForTemplate.class.getResourceAsStream(template + ".template.pdf"));
			stream = new ByteArrayOutputStream();
			stamper = new PdfStamper(reader, stream);
			
			//字体
			BaseFont baseFont = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
			tableFont = new Font(baseFont, 10, Font.NORMAL);
			
			AcroFields form = stamper.getAcroFields();
			form.addSubstitutionFont(baseFont);
			
			//Field(含Image)
			Iterator<String> it = form.getFields().keySet().iterator();
			while (it.hasNext()) {
				String name = it.next().toString();
				if (name.startsWith(IMAGE_PREFIX)) {
					if (null != imageParams && null != imageParams.get(name)) {
						// 通过域名获取所在页和坐标，左下角为起点 
						int pageNo = form.getFieldPositions(name).get(0).page;
						Rectangle signRect = form.getFieldPositions(name).get(0).position;
						float x = signRect.getLeft();
						float y = signRect.getBottom();
						
						Image image = Image.getInstance(imageParams.get(name));
						PdfContentByte under = stamper.getOverContent(pageNo);
						image.scaleToFit(signRect.getWidth(), signRect.getHeight());
						image.setAbsolutePosition(x, y);
						under.addImage(image);
					}
				}
				else if (null != params && null != params.get(name)) {
					form.setField(name, params.get(name).toString());
				}
			}

			if (null != pdfTable) {
				if (null != pdfTable && null != pdfTable.getHead()) {
					PdfPTable table = new PdfPTable(pdfTable.getWidths());
//					table.setSpacingBefore(10F);
//					table.setSpacingAfter(10F);
					table.setWidthPercentage(100F);
					
					for (PdfTableCell pdfTableCell : pdfTable.getHead().getCells()) {
						PdfPCell cell = new PdfPCell(
							new Paragraph(pdfTableCell.getData(),  tableFont)
						);
						if (pdfTableCell.getColspan() > 1) {
							cell.setColspan(pdfTableCell.getColspan());
						}
						if (pdfTableCell.getRowspan() > 1) {
							cell.setRowspan(pdfTableCell.getRowspan());
						}
						table.addCell(cell);
					}
					
					if(pdfTable.getRows()!=null){
						for (PdfTableRow pdfTableRow : pdfTable.getRows()) {
							for (PdfTableCell pdfTableCell : pdfTableRow.getCells()) {
								PdfPCell cell = new PdfPCell(
										new Paragraph(pdfTableCell.getData(),  tableFont)
										);
								if (pdfTableCell.getColspan() > 1) {
									cell.setColspan(pdfTableCell.getColspan());
								}
								if (pdfTableCell.getRowspan() > 1) {
									cell.setRowspan(pdfTableCell.getRowspan());
								}
								table.addCell(cell);
							}
						}
					}
					
					int pageNo = form.getFieldPositions(TABLE_DETAIL).get(0).page;
					Rectangle signRect = form.getFieldPositions(TABLE_DETAIL).get(0).position;
					float x = signRect.getLeft();
					float y = signRect.getTop();
					
					table.setTotalWidth(signRect.getWidth());
					
					PdfContentByte cb = stamper.getOverContent(pageNo);
					table.writeSelectedRows(0, -1, x, y, cb);
				}
			}
			
 			stamper.setFormFlattening(true);
			stamper.close();
		}
		catch (Throwable e) {
			throw new Exception(e);
		}
		finally {
			if (null != stamper) {
				stamper.close();
			}
			if (null != reader) {
				reader.close();
			}
		}
	}
	
	/**
	 * 输出至流
	 * @param output
	 * @throws Exception
	 */
	public void export(OutputStream output) throws Exception {
		Document document = null;
		try {
			document = new Document();
			PdfCopy copy = new PdfCopy(document, output);
			document.open();
			PdfImportedPage importPage = copy.getImportedPage(
				new PdfReader(stream.toByteArray()),
				1
			);
			copy.addPage(importPage);
		}
		catch (Throwable e) {
			throw new Exception(e);
		}
		finally {
			if (null != document) {
				document.close();
			}
		}
	}
	
}

